package com.dt.platform.hr.service.impl;

import javax.annotation.Resource;

import com.dt.platform.constants.enums.hr.PaperQuestionTypeEnum;
import com.dt.platform.domain.hr.PaperQuestionItem;
import com.dt.platform.domain.hr.PaperQuestionRel;
import com.dt.platform.domain.hr.meta.PaperQuestionMeta;
import com.dt.platform.hr.service.IPaperQuestionRelService;
import com.github.foxnic.commons.lang.StringUtil;
import com.github.foxnic.dao.data.RcdSet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.github.foxnic.dao.entity.ReferCause;
import com.github.foxnic.commons.collection.MapUtil;
import java.util.Arrays;


import com.dt.platform.domain.hr.PaperQuestion;
import com.dt.platform.domain.hr.PaperQuestionVO;
import java.util.List;
import com.github.foxnic.api.transter.Result;
import com.github.foxnic.dao.data.PagedList;
import com.github.foxnic.dao.entity.SuperService;
import com.github.foxnic.dao.spec.DAO;
import java.lang.reflect.Field;
import com.github.foxnic.commons.busi.id.IDGenerator;
import com.github.foxnic.sql.expr.ConditionExpr;
import com.github.foxnic.api.error.ErrorDesc;
import com.github.foxnic.dao.excel.ExcelWriter;
import com.github.foxnic.dao.excel.ValidateResult;
import com.github.foxnic.dao.excel.ExcelStructure;
import java.io.InputStream;
import com.github.foxnic.sql.meta.DBField;
import com.github.foxnic.dao.data.SaveMode;
import com.github.foxnic.dao.meta.DBColumnMeta;
import com.github.foxnic.sql.expr.Select;
import java.util.ArrayList;
import com.dt.platform.hr.service.IPaperQuestionService;
import org.github.foxnic.web.framework.dao.DBConfigs;
import java.util.Date;
import java.util.Map;
import java.util.logging.Logger;

/**
 * <p>
 * 考试题目服务实现
 * </p>
 * @author 金杰 , maillank@qq.com
 * @since 2024-09-14 14:55:31
*/


@Service("HrPaperQuestionService")

public class PaperQuestionServiceImpl extends SuperService<PaperQuestion> implements IPaperQuestionService {

	@Autowired
	private IPaperQuestionRelService paperQuestionRelService;

	@Autowired
	private IPaperQuestionService paperQuestionService;
	/**
	 * 注入DAO对象
	 * */
	@Resource(name=DBConfigs.PRIMARY_DAO) 
	private DAO dao=null;

	/**
	 * 获得 DAO 对象
	 * */
	public DAO dao() { return dao; }




	@Override
	public Object generateId(Field field) {
		return IDGenerator.getSnowflakeIdString();
	}


	/**
	 * 添加，根据 throwsException 参数抛出异常或返回 Result 对象
	 *
	 * @param paperQuestion  数据对象
	 * @param throwsException 是否抛出异常，如果不抛出异常，则返回一个失败的 Result 对象
	 * @return 结果 , 如果失败返回 false，成功返回 true
	 */
	@Override
	public Result insert(PaperQuestion paperQuestion,boolean throwsException) {
		if(StringUtil.isBlank(paperQuestion.getPaperId())){
			paperQuestion.setPaperId(paperQuestion.getSelectedCode());
		}
		if(PaperQuestionTypeEnum.JUDGE.code().equals(paperQuestion.getQuestionType())){
			RcdSet rs=dao.query("select selected,count(1) cnt from hr_paper_question_item where question_id=? group by selected",paperQuestion.getSelectedCode());
			if(rs.size()!=2){
				return ErrorDesc.failureMessage("判断题至少需要两个选项,一个正确一个为错误");
			}
			for(int i=0;i<rs.size(); i++){
				if(rs.getRcd(i).getInteger("cnt")!=1){
					return ErrorDesc.failureMessage("判断题必须一个正确，一个错误");
				}
			}

		}else if(PaperQuestionTypeEnum.RADIO.code().equals(paperQuestion.getQuestionType())){
			if(!(dao.queryRecord("select count(1) cnt from hr_paper_question_item where selected='right' and question_id=?",paperQuestion.getSelectedCode()).getInteger("cnt")==1)){
				return ErrorDesc.failureMessage("单选题请选择一个正确的答案");
			}
		}else if(PaperQuestionTypeEnum.CHOICE.code().equals(paperQuestion.getQuestionType())){
			if(dao.queryRecord("select count(1) cnt from hr_paper_question_item where selected='right' and question_id=?",paperQuestion.getSelectedCode()).getInteger("cnt")==0){
				return ErrorDesc.failureMessage("多选题至少存在一个正确的答案");
			}
		}



		Result r=super.insert(paperQuestion,throwsException);
		if(r.isSuccess()){
			dao.execute("update hr_paper_question_item set question_id=? where question_id=?",paperQuestion.getId(),paperQuestion.getSelectedCode());
			dao.fill(paperQuestion).with(PaperQuestionMeta.PAPER_QUESTION_ITEM_LIST).execute();
			List<PaperQuestionItem> itemList=paperQuestion.getPaperQuestionItemList();
			for(int i=0;i<itemList.size();i++){
				String code="";
				if(i==0){
					code="A";
				}else if(i==1){
					code="B";
				}else if(i==2){
					code="C";
				}else if(i==3){
					code="D";
				}else if(i==4){
					code="E";
				}else if(i==5){
					code="F";
				}else if(i==6){
					code="G";
				}else if(i==7){
					code="H";
				}else if(i==8){
					code="I";
				}else if(i==9){
					code="J";
				}else if(i==10){
					code="K";
				}
				if(PaperQuestionTypeEnum.RADIO.code().equals(paperQuestion.getQuestionType())
				||PaperQuestionTypeEnum.TEXTAREA.code().equals(paperQuestion.getQuestionType())
				||PaperQuestionTypeEnum.CHOICE.code().equals(paperQuestion.getQuestionType())){
					dao.execute("update hr_paper_question_item set code=? where id=?",code,itemList.get(i).getId());
				}else if(PaperQuestionTypeEnum.JUDGE.code().equals(paperQuestion.getQuestionType())){
					dao.execute("update hr_paper_question_item set code=? where id=?",code,itemList.get(i).getId());
				}
			}
		}
		return r;
	}


	@Override
	public Result dataSelect(String queryOwner, String selectedCode, List<String> ids) {
		if("paperSelect".equals(queryOwner)){
			ConditionExpr expr=new ConditionExpr();
			if(ids.size()>0){
				expr.andIn("id",ids);
				expr.and("id not in (select question_id from hr_paper_question_rel where paper_id=? and deleted=0)",selectedCode);
				List<PaperQuestion> list=paperQuestionService.queryList(expr);
				for(int i=0;i<list.size();i++){
					PaperQuestionRel obj=new PaperQuestionRel();
					obj.setPaperId(selectedCode);
					obj.setQuestionId(list.get(i).getId());
					obj.setQuestionName(list.get(i).getName());
					obj.setQuestionImageId(list.get(i).getImageId());
					obj.setQuestionFileId(list.get(i).getFileId());
					obj.setScore(list.get(i).getScore());
					obj.setQuestionType(list.get(i).getQuestionType());
					obj.setLearnPaperId(list.get(i).getPaperId());
					paperQuestionRelService.insert(obj,false);
				}
			}


		}
		return ErrorDesc.success();
	}

	@Override
	public Result validQuestion(String id){
		PaperQuestion paperQuestion=this.getById(id);
		if(PaperQuestionTypeEnum.JUDGE.code().equals(paperQuestion.getQuestionType())){
			RcdSet rs=dao.query("select selected,count(1) cnt from hr_paper_question_item where question_id=? group by selected",paperQuestion.getId());
			if(rs.size()!=2){
				return ErrorDesc.failureMessage("判断题至少需要两个选项,一个正确一个为错误");
			}
			for(int i=0;i<rs.size(); i++){
				if(rs.getRcd(i).getInteger("cnt")!=1){
					return ErrorDesc.failureMessage("判断题必须一个正确，一个错误");
				}
			}
		}else if(PaperQuestionTypeEnum.RADIO.code().equals(paperQuestion.getQuestionType())){
			if(!(dao.queryRecord("select count(1) cnt from hr_paper_question_item where selected='right' and question_id=?",paperQuestion.getId()).getInteger("cnt")==1)){
				return ErrorDesc.failureMessage("单选题请选择一个正确的答案");
			}
		}else if(PaperQuestionTypeEnum.CHOICE.code().equals(paperQuestion.getQuestionType())){
			if(dao.queryRecord("select count(1) cnt from hr_paper_question_item where selected='right' and question_id=?",paperQuestion.getId()).getInteger("cnt")==0){
				return ErrorDesc.failureMessage("多选题至少存在一个正确的答案");
			}
		}
		return ErrorDesc.success();
	}


	/**
	 * 添加，如果语句错误，则抛出异常
	 * @param paperQuestion 数据对象
	 * @return 插入是否成功
	 * */
	@Override
	public Result insert(PaperQuestion paperQuestion) {
		return this.insert(paperQuestion,true);
	}

	/**
	 * 批量插入实体，事务内
	 * @param paperQuestionList 实体数据清单
	 * @return 插入是否成功
	 * */
	@Override
	public Result insertList(List<PaperQuestion> paperQuestionList) {
		return super.insertList(paperQuestionList);
	}

	
	/**
	 * 按主键删除考试题目
	 *
	 * @param id 主键
	 * @return 删除是否成功
	 */
	public Result deleteByIdPhysical(String id) {
		PaperQuestion paperQuestion = new PaperQuestion();
		if(id==null) return ErrorDesc.failure().message("id 不允许为 null 。");
		paperQuestion.setId(id);
		try {
			boolean suc = dao.deleteEntity(paperQuestion);
			return suc?ErrorDesc.success():ErrorDesc.failure();
		}
		catch(Exception e) {
			Result r= ErrorDesc.failure();
			r.extra().setException(e);
			return r;
		}
	}
	
	/**
	 * 按主键删除考试题目
	 *
	 * @param id 主键
	 * @return 删除是否成功
	 */
	public Result deleteByIdLogical(String id) {
		PaperQuestion paperQuestion = new PaperQuestion();
		if(id==null) return ErrorDesc.failure().message("id 不允许为 null 。");
		paperQuestion.setId(id);
		paperQuestion.setDeleted(true);
		paperQuestion.setDeleteBy((String)dao.getDBTreaty().getLoginUserId());
		paperQuestion.setDeleteTime(new Date());
		try {
			boolean suc = dao.updateEntity(paperQuestion,SaveMode.NOT_NULL_FIELDS);
			return suc?ErrorDesc.success():ErrorDesc.failure();
		}
		catch(Exception e) {
			Result r= ErrorDesc.failure();
			r.extra().setException(e);
			return r;
		}
	}

	/**
	 * 更新，如果执行错误，则抛出异常
	 * @param paperQuestion 数据对象
	 * @param mode 保存模式
	 * @return 保存是否成功
	 * */
	@Override
	public Result update(PaperQuestion paperQuestion , SaveMode mode) {
		return this.update(paperQuestion,mode,true);
	}

	/**
	 * 更新，根据 throwsException 参数抛出异常或返回 Result 对象
	 * @param paperQuestion 数据对象
	 * @param mode 保存模式
	 * @param throwsException 是否抛出异常，如果不抛出异常，则返回一个失败的 Result 对象
	 * @return 保存是否成功
	 * */
	@Override
	public Result update(PaperQuestion paperQuestion , SaveMode mode,boolean throwsException) {

		 Result validR=validQuestion(paperQuestion.getId());
		 if(!validR.isSuccess()){
			return validR;
		 }

		Result r=super.update(paperQuestion , mode , throwsException);
		if(r.isSuccess()){
			dao.fill(paperQuestion).with(PaperQuestionMeta.PAPER_QUESTION_ITEM_LIST).execute();
			List<PaperQuestionItem> itemList=paperQuestion.getPaperQuestionItemList();
			for(int i=0;i<itemList.size();i++){
				String code="";
				if(i==0){
					code="A";
				}else if(i==1){
					code="B";
				}else if(i==2){
					code="C";
				}else if(i==3){
					code="D";
				}else if(i==4){
					code="E";
				}else if(i==5){
					code="F";
				}else if(i==6){
					code="G";
				}else if(i==7){
					code="H";
				}else if(i==8){
					code="I";
				}else if(i==9){
					code="J";
				}else if(i==10){
					code="K";
				}
				if(PaperQuestionTypeEnum.RADIO.code().equals(paperQuestion.getQuestionType())
						||PaperQuestionTypeEnum.TEXTAREA.code().equals(paperQuestion.getQuestionType())
						||PaperQuestionTypeEnum.CHOICE.code().equals(paperQuestion.getQuestionType())){
					dao.execute("update hr_paper_question_item set code=? where id=?",code,itemList.get(i).getId());
				}else if(PaperQuestionTypeEnum.JUDGE.code().equals(paperQuestion.getQuestionType())){
					dao.execute("update hr_paper_question_item set code=? where id=?",code,itemList.get(i).getId());
				}
			}
		}
		return r;
	}

	/**
	 * 更新实体集，事务内
	 * @param paperQuestionList 数据对象列表
	 * @param mode 保存模式
	 * @return 保存是否成功
	 * */
	@Override
	public Result updateList(List<PaperQuestion> paperQuestionList , SaveMode mode) {
		return super.updateList(paperQuestionList , mode);
	}

	
	/**
	 * 按主键更新考试题目
	 *
	 * @param id 主键
	 * @return 是否更新成功
	 */
	public boolean update(DBField field,Object value , String id) {
		if(id==null) throw new IllegalArgumentException("id 不允许为 null ");
		if(!field.table().name().equals(this.table())) throw new IllegalArgumentException("更新的数据表["+field.table().name()+"]与服务对应的数据表["+this.table()+"]不一致");
		int suc=dao.update(field.table().name()).set(field.name(), value).where().and("id = ? ",id).top().execute();
		return suc>0;
	}

	
	/**
	 * 按主键获取考试题目
	 *
	 * @param id 主键
	 * @return PaperQuestion 数据对象
	 */
	public PaperQuestion getById(String id) {
		PaperQuestion sample = new PaperQuestion();
		if(id==null) throw new IllegalArgumentException("id 不允许为 null ");
		sample.setId(id);
		return dao.queryEntity(sample);
	}

	/**
	 * 等价于 queryListByIds
	 * */
	@Override
	public List<PaperQuestion> getByIds(List<String> ids) {
		return this.queryListByIds(ids);
	}

	@Override
	public List<PaperQuestion> queryListByIds(List<String> ids) {
		return super.queryListByUKeys("id",ids);
	}

	@Override
	public Map<String, PaperQuestion> queryMapByIds(List<String> ids) {
		return super.queryMapByUKeys("id",ids, PaperQuestion::getId);
	}



	/**
	 * 查询实体集合，默认情况下，字符串使用模糊匹配，非字符串使用精确匹配
	 *
	 * @param sample  查询条件
	 * @return 查询结果
	 * */
	@Override
	public List<PaperQuestion> queryList(PaperQuestionVO sample) {
		return super.queryList(sample);
	}


	/**
	 * 分页查询实体集，字符串使用模糊匹配，非字符串使用精确匹配
	 *
	 * @param sample  查询条件
	 * @param pageSize 分页条数
	 * @param pageIndex 页码
	 * @return 查询结果
	 * */
	@Override
	public PagedList<PaperQuestion> queryPagedList(PaperQuestionVO sample, int pageSize, int pageIndex) {
		return super.queryPagedList(sample, pageSize, pageIndex);
	}

	/**
	 * 分页查询实体集，字符串使用模糊匹配，非字符串使用精确匹配
	 *
	 * @param sample  查询条件
	 * @param condition 其它条件
	 * @param pageSize 分页条数
	 * @param pageIndex 页码
	 * @return 查询结果
	 * */
	@Override
	public PagedList<PaperQuestion> queryPagedList(PaperQuestion sample, ConditionExpr condition, int pageSize, int pageIndex) {
		return super.queryPagedList(sample, condition, pageSize, pageIndex);
	}

	/**
	 * 检查 实体 是否已经存在 , 判断 主键值不同，但指定字段的值相同的记录是否存在
	 *
	 * @param paperQuestion 数据对象
	 * @return 判断结果
	 */
	public Boolean checkExists(PaperQuestion paperQuestion) {
		//TDOD 此处添加判断段的代码
		//boolean exists=super.checkExists(paperQuestion, SYS_ROLE.NAME);
		//return exists;
		return false;
	}

	/**
	 * 批量检查引用
	 * @param ids  检查这些ID是否又被外部表引用
	 * */
	@Override
	public <T> Map<T, ReferCause> hasRefers(List<T> ids) {
		// 默认无业务逻辑，返回此行；有业务逻辑需要校验时，请修改并使用已注释的行代码！！！
		return MapUtil.asMap(ids,new ReferCause(false));
		// return super.hasRefers(FoxnicWeb.BPM_PROCESS_INSTANCE.FORM_DEFINITION_ID,ids);
	}





}